package com.aiolos.weather.service.impl;

import com.aiolos.weather.service.WeatherDataService;
import com.aiolos.weather.vo.WeatherResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class WeatherDataServiceImpl implements WeatherDataService {

    private static final String WEATHER_URL = "http://wthrcdn.etouch.cn/weather_mini";
    private static final Long TIME_OUT = 1800L;  //Redis过期时间：1800s

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 根据城市id查询天气数据
     * @param cityId
     * @return
     */
    @Override
    public WeatherResponse getDataByCityId(String cityId) {
        String url = WEATHER_URL + "?citykey=" + cityId.trim();
        return getWeatherResponse(url);
    }

    @Override
    public WeatherResponse getDataByCityName(String cityName) {
        String url = WEATHER_URL + "?city=" + cityName.trim();
        return getWeatherResponse(url);
    }

    /**
     * 根据城市id同步天气数据
     * @param cityId
     */
    @Override
    public void syncWeatherDataByCityId(String cityId) {
        String url = WEATHER_URL + "?citykey=" + cityId.trim();
        saveWeatherDataToRedis(url);
    }

    /**
     * 保持天气数据到Redis
     * @param url
     */
    private void saveWeatherDataToRedis(String url){
        String stringBody = null;
        // 从缓存中取数据
        ValueOperations<String, String> ops =  stringRedisTemplate.opsForValue();

        //调用服务接口获取数据，
        ResponseEntity<String> respString = restTemplate.getForEntity(url, String.class);

        if(respString.getStatusCodeValue() == 200){
            stringBody = respString.getBody();
        }

        //将数据保存到缓存中：set(key,value,过期时间，时间单位)
        ops.set(url, stringBody, TIME_OUT, TimeUnit.SECONDS);
    }

    /**
     * V1.0 根据url获取WeatherResponse数据
     * V2.0 使用Redis缓存数据
     * @param url
     * @return
     */
    private WeatherResponse getWeatherResponse(String url){
        WeatherResponse result = null;
        String stringBody = null;
        ObjectMapper mapper = new ObjectMapper();
        // 从缓存中取数据
        ValueOperations<String, String> ops =  stringRedisTemplate.opsForValue();

        //V2.0 先从缓存中取数据
        if(stringRedisTemplate.hasKey(url)){
            log.info("Redis has data");
            stringBody = ops.get(url);
        }else{
            log.info("Redis do not have data");
            //V1.0 使用RestTemplate发送HTTP请求
            //V2.0 //缓存中没有才调用服务接口获取数据，
            ResponseEntity<String> respString = restTemplate.getForEntity(url, String.class);

            if(respString.getStatusCodeValue() == 200){
                stringBody = respString.getBody();
            }

            //V2.0  将数据保存到缓存中：set(key,value,过期时间，时间单位)
            ops.set(url, stringBody, TIME_OUT, TimeUnit.SECONDS);
        }

        //将json格式的字符串转换为Java对象
        try {
            result = mapper.readValue(stringBody, WeatherResponse.class);
        } catch (JsonProcessingException e) {
            log.error("Error!", e);
        }

        return result;
    }
}
